perm filename DEFVST.LSP[MAC,LSP]1 blob sn#447796 filedate 1979-06-07 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	 DEFVST						-*-LISP-*-
C00010 00003		CONSTRAINTS, and INITIAL VALUES
C00015 00004	 How to construct structures
C00019 00005
C00024 00006
C00030 00007	 DEFVST
C00042 ENDMK
CāŠ—;
;;; DEFVST						-*-LISP-*-

;;; Acronym for "DEFine a Vector-like STructure"
;;; All entries in a Vector-like structure are "pointers" (FIXNUMs, LISTs, etc)
;;; Future plans call for
;;;	DEFBST		-  "DEFine a Bitstring-like STructure", useful where
;;;			     the structure is an interface to some memory
;;;			     block required to be sequential by, say, operating
;;;			     system conventions, or hardware needs.
;;;	DEFSTRUCT 	-  "DEFine a general STRUCTure"
;;; 			    which will be done by composing DEFVST and DEFBST.
;;; Vector-like structures are implemented as VECTORs, which are emulated in
;;;	maclisp by HUNKs, and on the LISPMachine by 1-dimensional
;;;	ART-Q arrays;  the package "NILAID" has the emulators.

;;; Free (global) variables controlling actions:
;;;	CONSTRUCTOR-NAMESTRING-PREFIX 	- constructor name is obtained by 
;;;					    concatenating this string with the
;;;					    structure name.
;;;	SELECTOR-NAMESTRING-STYLE	- ()    ==> selector macro name is same
;;;						    as keyword (variable name).
;;;					- "xxx" ==> selector macro name gotten
;;;						    by concatenating structure 
;;;						    name, "xxx", and keyword.
;;;	DEFMACRO-DISPLACE-CALL		- whether or not macro instances should
;;;					  try to clobber with DISPLACE.  See
;;; 					  comments in DEFMAC package.

;;;  Basic macros: 	DEFVST  for defining a structure
;;;			SETVST  for updating a selected component
;;;			  (and SETF)
;;;  Usage is like:
;;;	(DEFVST SHIP 
;;;		(X-POSITION : FIXNUM) 
;;;		Y-POSITION 
;;;		(MASS = 1000.) 
;;;		COLOR )
;;;	(SETVST (SHIP-X-POSITION QE2) 109.)
;;;  or alternatively, since SETVST is abbreviated by SETF, 
;;;	(SETF (SHIP-X-POSITION QE2) 109.)
;;;  The SETVST macro is used in conjunction with DEFVST.  The example 
;;;  use of DEFVST "defines" a vector-like structure of 4 components;  
;;;  the generic name of this structure is "SHIP", and the components are 
;;;  identified by the ordering of what are called keywords -  X-POSITION, 
;;;  Y-POSITION, MASS, and COLOR.  Each "definition" causes the creation of 
;;;	1) A constructor macro, whose name (normally) is obtained by prefixing
;;;	   the string "CONS-A-" onto the generic name of the structure.
;;;	   In the example, this becomes CONS-A-SHIP.  The constructor
;;;	   permits installing values into the component slots at instantiation
;;;	   time, which are evaluated from either the (default) forms supplied 
;;;	   by the invocation of DEFVST, or from the forms obtained by keyword 
;;;	   parameters in the instantiating form.  E.g. 
;;;		(CONS-A-BANK DOLLARS (PLUS 300. WALLET) MANAGER '|Jones, J.|)
;;;	   would put the numerical value of  300.+WALLET  in the DOLLARS 
;;;	   component of a newly-created bank, and install |Jones, J.| as 
;;;	   its MANAGER.
;;; 	2) N selector macros, one for each keyword (which denotes one
;;;	   component slot), which are obtained (normally) by concatenating
;;;	   the generic name, a "-", and the keyword name.  In the example,
;;;	   we have SHIP-X-POSITION, SHIP-Y-POSITION, SHIP-MASS, and
;;;	   SHIP-COLOR.
;;;		2a: (SHIP-X-POSITION QE2) 
;;;		     to obtain the x-coordinate of QE2
;;;		2b: (SETVST (SHIP-X-POSITION QE2) 109.)
;;;		     to change the x-coordinate to of QE2 to 109.
;;;	3) an information structure, stored as the STRUCT=INFO property
;;;	   of the generic name symbol.  This information has the shape
;;;		(DEFVST STRUCT=INFO 
;;;			INDICATOR+GENERIC-NAME 	
;;;			CONSTRUCTOR-NAME 
;;;			NUMBER-OF-NAMED-COMPONENTS 
;;;			COMPONENT-DEFAULT-INITIALIZATION-LISTS )
;;;
;;;	The indicator+generic name is a pair whose car is &STRUCT, so
;;;	  that there may be some chance of identifying these structures;
;;;	  the cdr is the name handed to DEFVST.
;;;	The zero'th element of the initializations is either (), or a
;;;	  3-list of the key-name, selector-name, and default size for the
;;;	  &REST component - the "block" of unnamed components in the
;;;	  structure.   The remaining elements of the initializations are
;;;	  the "initialization lists" for each named component:
;;;		(<key-name> <corresponding-selector>)
;;;				;() initial value, no restrictions
;;;		(<key-name> <corresponding-selector> <ini-val-form>)
;;;				;no restrictions
;;;		(<key-name> <corresponding-selector> 
;;;			    <ini-val-form> . <list-of-types-for-restrictions>)
;;;
;;; 	Using the ABBREV macro (see LIBDOC;ABBREV >), one can selectively
;;;	use other names, but the canonical constructor and canonical
;;;	selector names will still be created at define time.  E.g.
;;;	    (ABBREV MG BANK-MANAGER SENDOFF CONS-A-SHIP)

;;;	CONSTRAINTS, and INITIAL VALUES

;;;	### Warning - this section may not be fully correct, as of 2/21/79 ###

;;;	   Each of the components may be constrained to be a particular 
;;;	type datum, and may be initialized according to the form supplied
;;;	as default by the call to DEFVST.
;;;
;;;	   The syntax for a non-simple component specification is a list with
;;;	the first element beinng the key name, the item following the first 
;;;	"=" in the list being a form whose value is the default initial value 
;;;	for that component in any creations of instances of that structure, 
;;;	and the element following the first ":" is either a type name or list 
;;;	of type names that restricts any creating instance from supplying an 
;;;	initial value of the wrong type.  If a key has a restriction 
;;;	associated with it, but no default initial-value form, then DEFVST 
;;;	picks some default value consistent with the restriction.
;;;	
;;; 	Consider the example
;;;	    (DEFVST BANK 
;;;	    	(DOLLARS : (FIXNUM FLONUM MUMBLE))
;;;	    	MANAGER 
;;;	    	(LIMIT = 1.0E6 : (FIXNUM FLONUM))
;;;	    	&REST 
;;;	    	 VAULTS 300.)
;;;
;;;	First, the macro invocation of DEFVST would expand into
;;;
;;;  (PROGN 'COMPILE
;;;	(EVAL-WHEN (EVAL COMPILE LOAD)
;;;		   (DEFPROP BANK
;;;			    #((&STRUCT . BANK)
;;;			      CONS-A-BANK 
;;;			      3 
;;;			      #((VAULTS BANK-VAULTS 30.)
;;;				(DOLLARS BANK-DOLLARS 0 FIXNUM FLONUM MUMBLE)
;;;				(MANAGER BANK-MANAGER)
;;;				(LIMIT BANK-LIMIT 1.0E6 FIXNUM FLONUM)))
;;;			    STRUCT=INFO)
;;;		   (DEFPROP CONS-A-BANK BANK CONSTRUCTOR)
;;;		   (DEFPROP BANK-DOLLARS (BANK 1) SELECTOR)
;;;		   (DEFPROP BANK-MANAGER (BANK 2) SELECTOR)
;;;		   (DEFPROP BANK-LIMIT (BANK 3) SELECTOR)
;;;		   (DEFPROP BANK-VAULTS (BANK 4 &REST) SELECTOR))
;;;	(DEFVST-DEFMACRO CONS-A-BANK (BANK-MACRO-ARG)
;;;			 (|defvst-construction/|| 'BANK BANK-MACRO-ARG))
;;;	(DEFVST-DEFMACRO BANK-DOLLARS (BANK-MACRO-ARG)
;;;			 `(VREF ,(cadr bank-macro-arg) 1))
;;;	(DEFVST-DEFMACRO BANK-MANAGER (BANK-MACRO-ARG)
;;;			 `(VREF ,(cadr bank-macro-arg) 2))
;;;	(DEFVST-DEFMACRO BANK-LIMIT (BANK-MACRO-ARG)
;;;			 `(VREF ,(cadr bank-macro-arg) 3))
;;;	(DEFVST-DEFMACRO BANK-VAULTS (BANK-MACRO-ARG)
;;;			 `(VREF ,(cadr bank-macro-arg)
;;;			        (+ 4 ,(caddr bank-macro-arg)))))
;;;	which is then evaluated, producing the four macro definitions, and 
;;;	DEFPROPping several informational properties.  [DEFVST-DEFMACRO is
;;; 	a version of DEFMACRO especially tailored to DEFVST]

;;; How to construct structures

;;;	After that, then, a "simple" creation instance is invoked by, say,
;;;			(CONS-A-BANK)
;;;	then yields a vector something like
;;;		#( (&STRUCT . BANK) 0 () 1.0E6 () . . . () )
;;;	- a bank with three named components, and with 30. unnamed 
;;;	components which are accessed as if VAULTS were a vector name. 
;;;	Note that the first element of the vector is a special 
;;;	"structure" indicator, so that code may certify whether something 
;;;	is indeed a structure.	But a more complex invocation
;;;
;;;	    (CONS-A-BANK DOLLARS (CASEQ VIP 
;;;	    			    (FEDERAL 15.0E9)
;;;	    			    (SAVINGS-&-LOAN 10.0E6)
;;;	    			    (MICKEY-MOUSE 1))
;;; 			  LIMIT (BANK-DOLLARS CURRENT-CONSTRUCTION)
;;; 			  VAULTS 12.)
;;;
;;;	illustrates three points of a creating instance - -
;;;	  (1) keywords paired with initial values are just alternating 
;;;	      pairs in the list, and 
;;;	  (2) the forms for initial values are substituted into a piece of
;;;	      code output by the macro, so that they are evaluated at 
;;;	      instantiation time, and
;;;	  (3) the variable CURRENT-CONSTRUCTION is dynamically bound to the
;;;	      structure being created so that it may be referenced; the 
;;;	      installing of initial values happens last.
;;;	Notice how this macro-expands -- 
;;;
;;;  (LET ((CURRENT-CONSTRUCTION (MAKE-VECTOR (1+ 41))))
;;;       (VSET CURRENT-CONSTRUCTION
;;;  		0
;;; 		(STRUCT=INFO-INDC (GET 'BANK 'STRUCT=INFO)))
;;;       (SETVST (BANK-DOLLARS CURRENT-CONSTRUCTION)
;;; 		  (|defvst-typchk/|| (CASEQ VIP
;;;  					    (FEDERAL 1.5E+10)
;;;  					    (SAVINGS-&-LOAN 10000000.0)
;;;  					    (MICKEY-MOUSE 1))
;;;  				     '(FIXNUM FLONUM MUMBLE)
;;;  				     'BANK-DOLLARS))
;;;       (SETVST (BANK-LIMIT CURRENT-CONSTRUCTION)
;;;  		  (|defvst-typchk/|| (BANK-DOLLARS CURRENT-CONSTRUCTION)
;;;  				     '(FIXNUM FLONUM)
;;;  				     'BANK-LIMIT))
;;;       CURRENT-CONSTRUCTION)
;;; 
;;;	This code might actually not run, since it could stop on a Restriction
;;;	Violation if the variable VIP does not have a value among
;;;		{FEDERAL, SAVINGS-&-LOAN, MICKEY-MOUSE}
;;;	for then it would turn up a () for the DOLLARS component, which
;;;	was specified to be restricted to fixnums.



(defun cmptime-eval macro (x) (and (eval (cadr x)) (eval (caddr x))))

(cmptime-eval (status feature maclisp) 
  `(OR (STATUS FEATURE NOLDMSG)
       (PROG2 (TERPRI)
	      (PRINC ',(implode (nconc (exploden '|;Loading DEFVST |)
				       (do ((x (exploden 
						(cond ((caddr (truename infile)))
						      ('/27)))
					       (cdr x)))
					   ((lessp 47. (car x) 58.)
					    x))
				       (exploden '| |)))))))



(eval-when (eval compile load)
	   (cond ((status feature complr)
		  (SPECIAL DEFMACRO-DISPLACE-CALL 
			   CURRENT-CONSTRUCTION  
			   CONSTRUCTOR-NAMESTRING-PREFIX 
			   SELECTOR-NAMESTRING-STYLE)
		  (*EXPR MACROEXPAND-1 
			 VECTORP 
			 |defvst-typchk/|| 
			 |defvst-construction/|| 
			 |defvst-instantiate/|| 
			 |defvst-getmarker/||) ))
)

(eval-when (eval compile)

(defun (IF-MACLISP macro) (x) 
       (and (status feature MACLISP)
	    `(PROGN 'COMPILE ,@(cdr x))))

(defun (IF-NOT-MACLISP macro) (x) 
       (and (not (status feature MACLISP))
	    `(PROGN 'COMPILE ,@(cdr x))))

(defun (IF-LISPM macro) (x) 
       (and (status feature LISPM)
	    `(PROGN 'COMPILE ,@(cdr x))))

(defun (IF-NOT-LISPM macro) (x) 
       (and (not (status feature LISPM))
	    `(PROGN 'COMPILE ,@(cdr x))))

(defun (IF-NIL macro) (x) 
       (and (status feature NIL)
	    `(PROGN 'COMPILE ,@(cdr x))))

(defun (IF-NOT-NIL macro) (x) 
       (and (not (status feature NIL))
	    `(PROGN 'COMPILE ,@(cdr x))))

 )


(eval-when (eval compile)
    (IF-MACLISP
     (defun macro-fun-get macro (x)  `(GET ,(cadr x) 'MACRO))
    )
    (IF-NOT-MACLISP 
     (defun MACRO-FUN-GET macro (x) 
	(let ((g (gensym)))
	     `((LAMBDA (,g)
		       (AND (SYMBOLP ,g)
			    (FBOUNDP ,g)
			    (SETQ ,g (FSYMEVAL ,g))
			    (NOT (ATOM ,g ))
			    (EQ (CAR ,g) 'MACRO)
			    (CDR ,g)))
	         ,(cadr x))))
     )
 )


(eval-when (eval compile load)
    (IF-MACLISP 
     (and (null (macro-fun-get 'ABBREVIATION))
	  (load (cond ((status feature its) '((DSK LIBLSP) ABBREV))
		      ('t `(,(car (get 'LAP 'AUTOLOAD)) ABBREV))) ))
     (and (null (getl 'setf '(fsubr macro)))
	  (abbreviation-displace setf setvst))
     (and (null (macro-fun-get 'VREF)) 
	  (load (cond ((status feature its) '((DSK LIBLSP) NILAID))
		      ('t `(,(car (get 'LAP 'AUTOLOAD)) NILAID))) )))
    (IF-LISPM 
     (and (null (macro-fun-get 'ABBREVIATION))
	  (load '|DSK:LISPM2;ABBREV QFASL|))
     (and (null (macro-fun-get 'VREF)) 
	  (load '|DSK:LISPM2;NILAID QFASL| )))
)


(eval-when (eval compile)
	   (abbreviation list-length length))

(eval-when (compile) 
    (macros t)
    (if-maclisp (*lexpr STRING-APPEND)  ))



(DECLARE (SETQ DEFMACRO-CHECK-ARGS ()
	       DEFMACRO-FOR-COMPILING 'T))


(AND (NOT (BOUNDP 'DEFMACRO-DISPLACE-CALL)) (SETQ DEFMACRO-DISPLACE-CALL 'T))
(AND (NOT (BOUNDP 'SELECTOR-NAMESTRING-STYLE)) 
     (SETQ SELECTOR-NAMESTRING-STYLE '"-"))
(AND (NOT (BOUNDP 'CONSTRUCTOR-NAMESTRING-PREFIX)) 
     (SETQ CONSTRUCTOR-NAMESTRING-PREFIX '"CONS-A-"))

(IF-MACLISP 
    (EVAL-WHEN (EVAL COMPILE LOAD)
	(AND (NOT (GET '|MACRO-macroexpander/|| 'MACRO))
	     (NOT (GET '|MACRO-macroexpander/|| 'AUTOLOAD))
	     (PUTPROP '|MACRO-macroexpander/|| 
		      (GET 'DEFMACRO 'AUTOLOAD) 
		      'AUTOLOAD))
	(AND (NOT (GET 'MACROEXPAND-1 'SUBR))
	     (NOT (GET 'MACROEXPAND-1 'AUTOLOAD))
	     (PUTPROP 'MACROEXPAND-1 (GET 'DEFMACRO 'AUTOLOAD) 'AUTOLOAD))
)

)


(DEFUN (DEFVST-DEFMACRO MACRO) (X)
   (CONS (COND (DEFMACRO-DISPLACE-CALL '|MACRO-macroexpander/||)
	       ('MACRO))
	 (CDR X)))



;;; The macros below represent a "hand-made" structure for the information
;;;  structure kept for STRUCTs, which might have been from


;;;  (DEFVST STRUCT=INFO INDC CNSN SIZE INIS)


(PROGN 'COMPILE 
       (EVAL-WHEN (COMPILE EVAL LOAD)
		  (DEFPROP CONS-A-STRUCT=INFO STRUCT=INFO CONSTRUCTOR)
		  (DEFPROP STRUCT=INFO-INDC (STRUCT=INFO 1) SELECTOR)
		  (DEFPROP STRUCT=INFO-CNSN (STRUCT=INFO 2) SELECTOR)
		  (DEFPROP STRUCT=INFO-SIZE (STRUCT=INFO 3) SELECTOR)
		  (DEFPROP STRUCT=INFO-INIS (STRUCT=INFO 4) SELECTOR)
		  )
       (DEFVST-DEFMACRO CONS-A-STRUCT=INFO (x) 
	       (|defvst-construction/|| 'STRUCT-INFO x))
       (DEFVST-DEFMACRO STRUCT=INFO-INDC (x) `(VREF ,(cadr x) 1))
       (DEFVST-DEFMACRO STRUCT=INFO-CNSN (x) `(VREF ,(cadr x) 2))
       (DEFVST-DEFMACRO STRUCT=INFO-SIZE (x) `(VREF ,(cadr x) 3))
       (DEFVST-DEFMACRO STRUCT=INFO-INIS (x) `(VREF ,(cadr x) 4))
)

;;; (DEFPROP STRUCT=INFO 
;;;	     #( (&STRUCT . STRUCT=INFO)			;Internal struct marker
;;;		(&STRUCT . STRUCT=INFO)			;Indicator+Generic name
;;;	        CONS-A-STRUCT=INFO			;Constructor-macro name
;;;	        4 					;Number of named keys
;;;	        #( ()					;&REST key/selector/len
;;;		   (INDC STRUCT=INFO-INDC () ) 		;Key-names with info
;;;		   (CNSN STRUCT=INFO-CNSN () )		;  for default initial
;;;		   (SIZE STRUCT=INFO-SIZE 4 ) 		;  settings
;;;		   (INIS STRUCT=INFO-INIS () )
;;;	      )					
;;;	     STRUCT=INFO)


(putprop 'STRUCT=INFO 
	 (vector '(&STRUCT . STRUCT=INFO)
		 '(&STRUCT . STRUCT=INFO)
		 'CONS-A-STRUCT=INFO
		 4 
		 (vector ()
			 '(indc struct=info-indc ())
			 '(cnsn struct=info-cnsn ())
			 '(size struct=info-size 0)
			 '(inis struct=info-inis ()))
		 )
	 'STRUCT=INFO )


;;; For now, SETF is only SETVST.  See comments above where ABBREV is loaded

(DEFUN (SETVST MACRO) (X)
   (LET ((VAL (NTH 2 X)) (ARGL (NTH 1 X)) LL SNAME)
	 ;Would like ((() (SNAME . ARGL) VAL) X)
	(SETQ SNAME (CAR ARGL) ARGL (CDR ARGL))
	(AND (OR (NULL ARGL)
		 (NOT (SYMBOLP SNAME))
		 (AND (SETQ LL (GET SNAME 'SELECTOR))	  	  ;either (NAME i)
		      (OR (COND ((NULL (CDDR LL)) (CDR ARGL))	  ; or (NAME i &REST)
				('T (NULL (CDR ARGL))))
			  (CDDR ARGL)))
		 (DO ((X (CADR X) (MACROEXPAND-1 X))
		      (BX) (BC)  (DEFMACRO-DISPLACE-CALL () ))
		     ((OR (ATOM X) 
			  (AND (EQ X BX) (EQ (CAR X) BC))
			  (EQ (CAR X) 'VREF)) 
		      (NOT (EQ (CAR (SETQ LL X)) 'VREF)))
		     (SETQ BC (CAR (SETQ BX X)))))
	     (ERROR '|Incorrect selector - SETVST| SNAME))
	`(VSET ,@(cdr ll) ,val)))

;;; DEFVST

(DEFUN (DEFVST MACRO) (X)
   (LET (  (SELKEYS (CDDR X)) (SNAME (CADR X))  (NKEYS 0)
	    ;Would like ((() SNAME . SELKEYS) X)   
	   (DEFMACRO-DISPLACE-CALL DEFMACRO-DISPLACE-CALL)
	   (SELECTOR-NAMESTRING-STYLE SELECTOR-NAMESTRING-STYLE)
	   (CONSTRUCTOR-NAMESTRING-PREFIX CONSTRUCTOR-NAMESTRING-PREFIX)
	   CONSTRUCTOR-NAME  RESTP  RESTKEY  RESTSIZEFORM  TYP  TMP 
	   SELMACDEFS  SELDEFPROPS  SELINIS  MAC-ARG-NM )
	(DECLARE (FIXNUM I NKEYS))
	(COND ((NOT (ATOM SNAME))
	       (DO L (CDR SNAME) (CDDR L) (NULL L)
		   (SET (CAR L) (EVAL (CADR L))))
	       (SETQ SNAME (CAR SNAME))))
	(AND (OR (NULL SNAME) (NOT (SYMBOLP SNAME)) (ATOM SELKEYS))
	     (ERROR '|Bad args - DEFVST| X))
	(SETQ NKEYS (LIST-LENGTH SELKEYS))
	(COND ((SETQ TMP (MEMQ '&REST SELKEYS))
	       (SETQ NKEYS (- NKEYS (LIST-LENGTH TMP))
		     RESTKEY (CADR TMP)
		     RESTSIZEFORM (CADDR TMP))
	       (AND (OR (NOT (SYMBOLP RESTKEY)) (NULL RESTSIZEFORM))
		    (ERROR '|Lossage in &REST variable - DEFVST| SELKEYS))))
	(AND (GET SNAME 'STRUCT=INFO)
	     (FORMAT MSGFILES '|}%Warning! }S is already a STRUCTURE | SNAME))
	(SETQ MAC-ARG-NM 
	      (INTERN (STRING-APPEND (GET-PNAME SNAME) '"-MACRO-ARG")))
	(SETQ CONSTRUCTOR-NAME 
	      (INTERN (STRING-APPEND CONSTRUCTOR-NAMESTRING-PREFIX 
				     (GET-PNAME SNAME))))
	 ; RESTP and SELINIS start out null here
	(DO ( (I 1 (1+ I)) (L SELKEYS (CDR L)) (FLAG) (KEYNM) (SELNM) )
	    ( (OR (NULL L) RESTP) )
	  (COND ((ATOM (SETQ KEYNM (CAR L))) 
		 (COND ((EQ KEYNM '&REST)
			(SETQ KEYNM RESTKEY  RESTP 'T)
			(AND (NOT (EQ RESTKEY (CADR L))) 
			     (ERROR '|&REST lossage DEFVST|))))
		 (SETQ TMP () ))
		('T (AND (OR (NULL (SETQ KEYNM (CAR KEYNM)))
			     (NOT (SYMBOLP KEYNM)))
			(ERROR '|Bad key-list - DEFVST| SELKEYS))
		    (COND ((ATOM (CDAR L)) (SETQ TMP () ))
			  ('T (SETQ FLAG () )
			      (AND (SETQ TYP (MEMQ '|:| (CDAR L)))
				   (PROG2 (SETQ FLAG 'T) 'T)
				   (SETQ TYP (COND ((ATOM (CADR TYP))
						    (LIST (CADR TYP)))
						   ((CADR TYP)))))
			      (SETQ TMP (COND ((SETQ TMP (MEMQ '= (CDAR L)))
					       (SETQ FLAG 'T)
					       (CADR TMP))
					      (TYP (CDR (ASSQ (CAR TYP)
							      '((FIXNUM . 0) 
								(FLONUM . 0.0)
								(BIGNUM . 500000000000000000000.)
								(SHORTFLOAT 0.0)
								(LIST . () )
								(SYMBOL . FOO)
								(VECTOR . () )	;change this
								(ARRAY . () )	;crap in the
								(HUNK . () )	;real NIL !
								)))) ))
			      (AND (NOT FLAG)
				   (ERROR '|Invalid initialization or restriction - DEFVST|
					  (CAR L)))
			      (SETQ TMP (CONS TMP TYP)))) ))
	  (SETQ SELNM (COND ((NULL SELECTOR-NAMESTRING-STYLE) KEYNM)
			    ((INTERN (STRING-APPEND (GET-PNAME SNAME) 
						    SELECTOR-NAMESTRING-STYLE 
						    (GET-PNAME KEYNM))))))
	  (PUSH (COND ((NOT RESTP) 
		        ;TMP has "(<initialization-form> <restrictions> ... )
		       (PUSH `(QUOTE (,keynm ,selnm ,@tmp)) SELINIS)
		       `(DEFVST-DEFMACRO ,selnm (,mac-arg-nm) 
			  `(VREF ,(cadr ,mac-arg-nm) ,,i)))
		      ('T (SETQ RESTP `(QUOTE (,keynm ,selnm ,restsizeform)))
			  `(DEFVST-DEFMACRO ,selnm (,mac-arg-nm)
			     `(VREF ,(cadr ,mac-arg-nm) 
				    (+ ,,(1+ nkeys) ,(caddr ,mac-arg-nm))))))
		SELMACDEFS)
	  (PUSH `(DEFPROP ,selnm 
			  (,sname  ,i . ,(and restp '(&REST))) 
			  SELECTOR) 
		SELDEFPROPS))
	`(PROGN 'COMPILE
		(EVAL-WHEN (EVAL COMPILE LOAD)
			    ;This abortive PUTPROP is here because MACLISP
			    ; cant handle reading or fasl'ing HUNKs
			   (PUTPROP 
			     ',sname 
			     (VECTOR (|defvst-getmarker/||)
				     ',(cons '&STRUCT sname)
				     ',constructor-name
				     ,nkeys 
				     (VECTOR . ,(cons restp (nreverse selinis))))
			     'STRUCT=INFO)
			   (DEFPROP ,constructor-name ,sname CONSTRUCTOR)
			   ,@(nreverse seldefprops) )
		(DEFVST-DEFMACRO ,constructor-name (,mac-arg-nm)
		       (|defvst-construction/|| ',sname ,mac-arg-nm))
		,@(nreverse selmacdefs))))


(DEFUN |defvst-construction/|| (SNAME ARGL)
  (PROG (SINFO OVERRIDES INIS ACCESSOR-MAC BL OL NOL RESTP NKEYS TOTSIZE TMP)
	(DECLARE (FIXNUM NKEYS TOTSIZE))
	(AND (SETQ OVERRIDES (CDR ARGL)) (PUSH () OVERRIDES))
	(AND (NOT (VECTORP (SETQ SINFO (GET SNAME 'STRUCT=INFO))))
	     (ERROR '|defvst-construction/|| ARGL))
;;; The following could be (DESETQ ((&STRUCT . STRUCT=INFO)
;;;				     INIS INIS 
;;;				     SIZE NKEYS) 
;;;				   SINFO)
	(SETQ INIS (STRUCT=INFO-INIS SINFO)
	      NKEYS (STRUCT=INFO-SIZE SINFO))
	(SETQ RESTP (VREF INIS 0))
	(SETQ TOTSIZE NKEYS)
	(AND RESTP 
	     (SETQ TOTSIZE 
		   (+ TOTSIZE (COND ((AND OVERRIDES (SETQ TMP (GET (CAR RESTP)
								   OVERRIDES)))
				     (COND ((EQ (TYPEP TMP) 'FIXNUM))
					   ((>= TMP 0))
					   ((ERROR '|Bad &REST arg quantity| 
						ARGL)))
				     TMP)
				    ((CADDR RESTP))))))
	(DO ( (I NKEYS (1- I)) (FLAG () () ) KEYNAME TYPL FORM )
	    ( (<= I 0) )
	  (DESETQ (KEYNAME ACCESSOR-MAC FORM . TYPL) (VREF INIS I))
	  (AND (SETQ TMP (GETL OVERRIDES (LIST KEYNAME)))
	       (SETQ FORM (CADR TMP) FLAG 'T))
	  (AND FORM 
	       (SETQ FORM `(SETVST (,accessor-mac CURRENT-CONSTRUCTION)
				   ,(cond ((null typl) form)
					  (`(|defvst-typchk/|| 
					     ,form
					     ',typl 
					     ',accessor-mac)))))
	       (COND (FLAG  (PUSH (CONS KEYNAME FORM) OL))
		     ('T (PUSH FORM BL)))))
	(AND OL (DO L (CDR OVERRIDES) (CDDR L) (NULL L)
		    (AND (SETQ TMP (ASSQ (CAR L) OL))
			 (PUSH (CDR TMP) NOL))))
	(RETURN `(LET ( (CURRENT-CONSTRUCTION (MAKE-VECTOR ,(1+ totsize))) )
		      (VSET CURRENT-CONSTRUCTION
			    0 
			    (STRUCT=INFO-INDC (get ',sname 'STRUCT=INFO)))
		      ,@(nreverse bl)
		      ,@(nreverse nol) 
		      CURRENT-CONSTRUCTION))))

(DEFUN |defvst-getmarker/|| () 
   (PROG (SINFO)
      A  (COND ((NULL (SETQ SINFO (GET 'STRUCT=INFO 'STRUCT=INFO)))
		(BREAK |Please Load DEFVST|)
		(GO A)))
	 (RETURN (STRUCT=INFO-INDC SINFO))))


(DEFUN |defvst-typchk/|| (VAL TYPL ACCESSOR-MAC)
    (PROG (NTYP SNAME KEY)
     A	 (AND (MEMQ (SETQ NTYP (TYPEP VAL)) TYPL) (RETURN VAL))
	  ;Accessor-macro name has a SELECTOR property of "(<sname> <index>)"
	  ; where <sname> is the structure name, and <index> is the vector
	  ; index corresponding to the key-name
	  ;For now, the first slot of a structure-vector is taken up by the 
	  ; &STRUCT marker, so the access of the initializations list(vector)
	  ; must be made to correspond.
	 (AND (NULL SNAME) 
	      (SETQ SNAME (NTH 0 (SETQ NTYP (GET ACCESSOR-MAC 'SELECTOR))) 
		    KEY (CAR (VREF (STRUCT=INFO-INIS (GET SNAME 'STRUCT=INFO))
				   (COND ((EQ (NTH 2 NTYP) '&REST) 0)
					 ((NTH 1 NTYP)))))))
	 (FORMAT MSGFILES 
		 '|}%;Restriction Violation while creating a }S structure.}%
;The }S component is being set to }S}%; which is supposed to be of type }S|
		 SNAME 
		 KEY 
		 VAL
		 (COND ((CDR TYPL) TYPL)
		       ((CAR TYPL))))
	 (SETQ VAL (ERROR '|DEFVST Restriction Violation| 
			  (LIST SNAME KEY VAL)
			  'WRNG-TYPE-ARG))
	 (GO A)))